/**
 * 
 */
package com.ubb.smartsearch.web;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.primefaces.model.LazyDataModel;

import com.ubb.smartsearch.controller.SearchHandlerLocal;
import com.ubb.smartsearch.searchengineif.entity.Result;

/**
 * @author Aron
 * 
 */
@ManagedBean
@ViewScoped
public class Index implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@EJB(beanName="SearchHandlerBean")
	private SearchHandlerLocal searchHandler;

	private LazyDataModel<Result> lazyModel;

	private String searchField;
	private boolean opened = false;

	private Locale currentLocale;
	private String selectedLanguage;
	private List<SelectItem> availableLocales;

	private String selectedAlgorithm;

	private String selectedTrainCorpus;

	private Double alfa;
	private Double beta;

	private boolean rocchioParametersVisible;

	@PostConstruct
	public void initialize() {
		setCurrentLocale(FacesContext.getCurrentInstance().getViewRoot()
				.getLocale());

		selectedLanguage = currentLocale.getLanguage();
		selectedAlgorithm = "rocchio";
		selectedTrainCorpus = "newsgroups";
		alfa = 16.0;
		beta = 4.0;
		rocchioParametersVisible = true;
		searchHandler.setRocchioParameters(alfa, beta);
	}

	public void search() {
		lazyModel = new LazyResultDataModel(searchHandler, 
				searchField);
	}

	public void train() {
		
			searchHandler.train(selectedTrainCorpus);
	}

	public void saveOptions() {
		
		searchHandler.changeAlgorithm(selectedAlgorithm, alfa, beta);
		
		if ("rocchio".equals(selectedAlgorithm)) {
			searchHandler.setRocchioParameters(alfa, beta);
		}
		
		if(lazyModel != null) {
			lazyModel = new LazyResultDataModel(searchHandler, 
					searchField);
		}

	}

	public void algorithmSelected(AjaxBehaviorEvent vce) {
		
		if ("rocchio".equals(selectedAlgorithm)) {
			rocchioParametersVisible = true;
		} else {
			rocchioParametersVisible = false;
		}
	}

	private void generateAvailableLocales() {
		availableLocales = new ArrayList<SelectItem>(0);

		// Add the default locale
		availableLocales.add(makeLocaleItem(FacesContext.getCurrentInstance()
				.getApplication().getDefaultLocale()));

		// Add any other supported locales
		for (Iterator<Locale> iter = FacesContext.getCurrentInstance()
				.getApplication().getSupportedLocales(); iter.hasNext();) {
			availableLocales.add(makeLocaleItem(iter.next()));
		}
	}

	public List<SelectItem> getAvailableLocales() {
		if (availableLocales == null) {
			generateAvailableLocales();
		}

		return availableLocales;
	}

	public void setAvailableLocales(List<SelectItem> availableLocales) {
		this.availableLocales = availableLocales;
	}

	private SelectItem makeLocaleItem(Locale toWrap) {
		if (toWrap != null) {
			return new SelectItem(toWrap.getLanguage(), toWrap.getDisplayName());
		}

		return null;
	}

	public void applyLocale(Locale toApply) {
		System.out.println("Apply Locale: " + toApply.getDisplayName() + " ("
				+ toApply.getLanguage() + ")");

		setCurrentLocale(toApply);

		FacesContext.getCurrentInstance().getViewRoot().setLocale(toApply);
	}

	public void localeChanged(ValueChangeEvent event) {
		if (event.getNewValue() != null) {
			applyLocale(new Locale(event.getNewValue().toString()));
		}
	}

	/**
	 * @return the searchField
	 */
	public String getSearchField() {
		return searchField;
	}

	/**
	 * @param searchField
	 *            the searchField to set
	 */
	public void setSearchField(String searchField) {
		this.searchField = searchField;
	}

	public boolean isOpened() {
		return opened;
	}

	public void setOpened(boolean opened) {
		this.opened = opened;
	}

	public void optionsOpened(ActionEvent event) {
		opened = !opened;
	}

	public void openEvent(ActionEvent event) {
		opened = true;
	}

	public void closeEvent(ActionEvent event) {
		opened = false;
	}

	/**
	 * @return the selectedLanguage
	 */
	public String getSelectedLanguage() {
		return selectedLanguage;
	}

	/**
	 * @param selectedLanguage
	 *            the selectedLanguage to set
	 */
	public void setSelectedLanguage(String selectedLanguage) {
		this.selectedLanguage = selectedLanguage;
	}

	/**
	 * @return the selectedAlgorithm
	 */
	public String getSelectedAlgorithm() {
		return selectedAlgorithm;
	}

	/**
	 * @param selectedAlgorithm
	 *            the selectedAlgorithm to set
	 */
	public void setSelectedAlgorithm(String selectedAlgorithm) {
		this.selectedAlgorithm = selectedAlgorithm;
	}

	/**
	 * @return the selectedTrainCorpus
	 */
	public String getSelectedTrainCorpus() {
		return selectedTrainCorpus;
	}

	/**
	 * @param selectedTrainCorpus
	 *            the selectedTrainCorpus to set
	 */
	public void setSelectedTrainCorpus(String selectedTrainCorpus) {
		this.selectedTrainCorpus = selectedTrainCorpus;
	}

	/**
	 * @return the alfa
	 */
	public Double getAlfa() {
		return alfa;
	}

	/**
	 * @param alfa
	 *            the alfa to set
	 */
	public void setAlfa(Double alfa) {
		this.alfa = alfa;
	}

	/**
	 * @return the beta
	 */
	public Double getBeta() {
		return beta;
	}

	/**
	 * @param beta
	 *            the beta to set
	 */
	public void setBeta(Double beta) {
		this.beta = beta;
	}

	/**
	 * @return the rocchioParametersVisible
	 */
	public boolean isRocchioParametersVisible() {
		return rocchioParametersVisible;
	}

	/**
	 * @param rocchioParametersVisible
	 *            the rocchioParametersVisible to set
	 */
	public void setRocchioParametersVisible(boolean rocchioParametersVisible) {
		this.rocchioParametersVisible = rocchioParametersVisible;
	}

	/**
	 * @return the currentLocale
	 */
	public Locale getCurrentLocale() {
		return currentLocale;
	}

	/**
	 * @param currentLocale
	 *            the currentLocale to set
	 */
	public void setCurrentLocale(Locale currentLocale) {
		this.currentLocale = currentLocale;
	}

	/**
	 * @return the lazyModel
	 */
	public LazyDataModel<Result> getLazyModel() {
		return lazyModel;
	}
}
